﻿//****************************************************************************
// Copyright (c) Microsoft Corporation. All rights reserved.
//****************************************************************************
using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.FxCop.Sdk;

namespace Microsoft.FxCop.Rules.ASP.MVC.Security
{
    sealed class ControllerActionShouldValidateInput : BaseIntrospectionRule
    {
        #region *** Constructor ***
        public ControllerActionShouldValidateInput()
            : base(typeof(ControllerActionShouldValidateInput).Name, "Microsoft.FxCop.Rules.ASP.MVC.Security.ASPMvcSecurityRules", typeof(ControllerActionShouldValidateInput).Assembly)
        {
        }
        #endregion

        #region *** Methods ***

        #region *** BaseIntrospectionRule ***
        public override ProblemCollection Check(Member member)
        {
            Method method;

            if ((method = (member as Method)) != null)
            {
                if (MVCHelper.IsControllerAction(method))
                {
                    AnalyzeMethodAttributes(method);
                }
            }

            return base.Problems;
        }
        #endregion

        #region *** Private ***

        private void AnalyzeMethodAttributes(Method method)
        {
            AttributeNode validateRequestAttribute = null;

            foreach (AttributeNode attrNode in method.Attributes)
            {
                if (attrNode.Type.FullName == "System.Web.Mvc.ValidateInputAttribute")
                {
                    validateRequestAttribute = attrNode;
                    break;
                }
            }

            if (validateRequestAttribute != null)
            {
                AnalyzeValidateRequestAttribute(validateRequestAttribute);
            }
        }

        private void AnalyzeValidateRequestAttribute(AttributeNode attrNode)
        {
            if (!((bool)(attrNode.Expressions[0] as Literal).Value))
            {
                ReportProblem();
            }
        }

        private void ReportProblem()
        {
            Problem problem = new Problem(base.GetResolution());
            base.Problems.Add(problem);
        }
        #endregion

        #endregion
    }
}
